1 /**
2 The following examples come from
3 $(LINK http://zetcode.com/db/sqlite/constraints/).
4 Even though it is a SQLite tutorial the point is to show how to use this package
5 which does not have to be just SQLite.
6  */
7 module test.examples_notnull;
8 
9 version(D_Ddoc)
10 {
11     ///
12     class BlankClassSoDocsWillBeGenerated { }
13 }
14 
15 /**
16 This example is for the NOT NULL constraint. The table
17 in SQL can be created by
18 $(D $(D $(D sql
19 CREATE TABLE People
20 (
21     Id INTEGER NOT NULL PRIMARY KEY,
22     LastName TEXT NOT NULL,
23     FirstName TEXT NOT NULL,
24     City TEXT
25 );
26 
27 )))
28 
29 I will create the singular class (or row class). The singular class
30 should include a dup method and the mixin KeyedItem. The columns in the
31 singular class should have a private member with getters and setters. No
32 plural class (or table class) is needed for this example.
33 
34 In making this package, I have made the assumption that the private member
35 begins with an underscore and the getters and setters have the same name
36 as the private member except no beginning underscore.
37 The keyed item must also have some Unique constraint and will not compile
38 without one.
39 
40 The setter method provided in KeyedItem should be used in your setters. This
41 will check if you are setting it to the same value, if the value causes any
42 check constraints to be violated and if everything goes well notifies the
43 plural class (or table) of the changes.
44  */
45 unittest
46 {
47     import db_constraints;
48 
49     // this is what I call the singular class
50     // you can also think of it as a row in the database.
51     // it contains all of the columns and tells us which
52     // columns have which constraints
53     class Person
54     {
55         private int _Id;
56         // marking Id with not null and primary key
57         @NotNull @PrimaryKeyColumn
58         @property int Id()
59         {
60             return _Id;
61         }
62         @property void Id(int value)
63         {
64             setter(_Id, value);
65         }
66 
67         private string _LastName;
68         // marking LastName with not null
69         @NotNull
70         @property string LastName()
71         {
72             return _LastName;
73         }
74         @property void LastName(string value)
75         {
76             setter(_LastName, value);
77         }
78 
79         private string _FirstName;
80         // marking FirstName with not null
81         @NotNull
82         @property string FirstName()
83         {
84             return _FirstName;
85         }
86         @property void FirstName(string value)
87         {
88             setter(_FirstName, value);
89         }
90 
91         private string _City;
92         // not marking City with anything
93         @property string City()
94         {
95             return _City;
96         }
97         @property void City(string value)
98         {
99             setter(_City, value);
100         }
101 
102         this(int Id_, string LastName_, string FirstName_, string City_)
103         {
104             this._Id = Id_;
105             this._LastName = LastName_;
106             this._FirstName = FirstName_;
107             this._City = City_;
108             // do not forget to initialize the keyed item!
109             initializeKeyedItem();
110         }
111 
112         // the keyed item mixin will create all the necessary
113         // checks for you
114         mixin KeyedItem!();
115     }
116 
117 
118     import std.exception : assertNotThrown, assertThrown;
119     // I will make a single row with values for all columns
120     // this does not throw an exception because none of the
121     // check constraints are violated.
122     assertNotThrown!CheckConstraintException(new Person(1, "Hanks",
123                                                         "Robert", "New York"));
124 
125     // the next Person throws a check constraint exception
126     // since we try to make a Person that has a null LastName
127     assertThrown!CheckConstraintException(new Person(2, null,
128                                                      "Marianne", "Chicago"));
129 }